<?php

namespace App\Models\Traits;

use App\Models\AttributeKey;
use App\Models\AttributeValue;
use Illuminate\Support\Facades\DB;
use Brick\Math\RoundingMode;

trait ProductSkuTrait
{
	public function pushPriceToProduct()
	{
		$sku = $this->product->skus()->orderBy('price_vip')->first();
		
		if (! $sku) return;
		
		$marketPrice = $sku->price;
		$lowestPrice = $sku->price_vip;
		$lowestPriceCost = $sku->price_cost;
		
		if ($marketPrice > 0 and $lowestPrice > 0 and $lowestPriceCost > 0) {
			$this->product->update([
				'price_lowest' => $lowestPrice,
				'price_market' => $marketPrice,
				'price_lowest_cost' => $lowestPriceCost,
			]);
		}
	}


	public function updateRewardsToSkus()
	{
		$sku = $this;
		if (! $sku) return;
		
		$rewards = $sku->rewards;
		$ownRewards = big_decimal(0);
		$parentRewards = big_decimal(0);
		
		$ownReawrdsPercent = cs('sale')->order_own_rewards_percent / 100;
		$parentReawrdsPercent = cs('sale')->order_parent_rewards_percent / 100;
		if(big_decimal($rewards)->isGreaterThan(0)){
			$ownRewards = big_decimal($rewards)->dividedBy(0.7 ,2 , RoundingMode::HALF_UP)->multipliedBy($ownReawrdsPercent);
			$parentRewards = big_decimal($rewards)->dividedBy(0.7 ,2 , RoundingMode::HALF_UP)->multipliedBy($parentReawrdsPercent);

		}else{
			if($sku->price_vip > $sku->price_cost){
				$rewards =$sku->price_vip - $sku->price_cost;
				$ownRewards = big_decimal($rewards)->multipliedBy($ownReawrdsPercent);
				$parentRewards = big_decimal($rewards)->multipliedBy($parentReawrdsPercent);
			}

		}
		return $sku->update([
			'own_rewards' => $ownRewards,
			'parent_rewards' => $parentRewards,
		]);

		
	}
	
	public function decreaseStock(int $amount)
	{
		if ($amount > 0 and $amount <= $this->stock) {
			$this->where('id', $this->id)
				->where('stock', '>=', $amount)
				->decrement('stock', $amount);
			return true;
		}
		return false;
	}
	
	public function increaseStock(int $amount)
	{
		if ($amount > 0) {
			$this->increment('stock', $amount);
		}
	}
	
	protected function syncAttributeWhenSaving()
	{
		$attrValues = $this->attr_value ?? [];
		if (count($attrValues) > 0) {
			DB::transaction(function () use ($attrValues) {
				$attrValueIndex = [];
				foreach ($attrValues as $key => $value) {
					$attrValue = AttributeValue::firstOrCreate([
						'product_id' => $this->product_id,
						'attribute_key_id' => $key,
						'value' => $value,
					]);
					$attrValueIndex[] = $attrValue->id;
				}
				sort($attrValueIndex);
				$this->attr_value_index = implode('-', $attrValueIndex);
			});
		}
	}
	
	protected function syncAttributeWhenSaved()
	{
		$allAttrValues = $this->product->attributeValues;
		$allSkuIndices = $this->product->skus->pluck('attr_value_index')->join('-');
		$allSkuIndices = array_unique(explode('-', $allSkuIndices));
		foreach ($allAttrValues as $value) {
			if (!in_array($value->id, $allSkuIndices)) {
				AttributeValue::destroy($value->id);
			}
		}
	}
	
	protected function syncAttributeWhenDeleting()
	{
		if ($this->attr_value_index) {
			$attrValueIndices = explode('-', $this->attr_value_index);
			foreach ($attrValueIndices as $deletedIndex) {
				$allSkuIndices = $this->product->skus->pluck('attr_value_index')->join('-');
				$allSkuIndices = array_unique(explode('-', $allSkuIndices));
				if (!in_array($deletedIndex, $allSkuIndices)) {
					AttributeValue::destroy($deletedIndex);
				}
			}
		}
	}
	
	public function syncAttribute($mode = 'saving')
	{
		if ($mode == 'saving') {
			$this->syncAttributeWhenSaving();
		}
		if ($mode == 'saved') {
			$this->syncAttributeWhenSaved();
		}
		if ($mode == 'deleting') {
			$this->syncAttributeWhenDeleting();
		}
	}
	
	public function getAttrKeyValue()
	{
		$attrKeyValue = null;
		if ($this->attr_value and count($this->attr_value) > 0) {
			$attrKeyValue = [];
			foreach ($this->attr_value as $k => $v) {
				$attrKey = AttributeKey::findOrFail($k);
				$attrKeyValue[] = "{$attrKey->key}:{$v}";
			}
		}
		return $attrKeyValue;
	}
	
	public function getAttrValueIndexArray()
	{
		return $this->attr_value_index ? explode('-', $this->attr_value_index) : null;
	}
}
